<?php
declare(strict_types=1);

namespace Service\CommodityService;

use App\Model\CommodityModel\CommodityArchives;
use App\Model\CommodityModel\CommodityDescription;
use Service\AppService\IdService;
use Service\AppService\SkuCodeBuilderService;
use Service\BaseService;
use Service\Code\Normal;
use Service\CommodityAttributeService\BrandInfoService;
use Service\CommodityAttributeService\ClassInfoService;
use Service\CommodityAttributeService\CommodityAttributeBaseService;
use Service\CommodityAttributeService\CountryInfoService;
use Service\CommodityAttributeService\UnitInfoService;
use Service\ConsumerService\ConsumerMapping\CommodityMapping;

class CommodityArchivesService extends BaseService
{
    /**
     * 匹配新的商品主资料
     * @param $condition
     * @return array
     */
    public function getConsumerMatchItem($condition): array
    {
        $goodsBase = array_column($condition, 'base');
        $barCodeMatchArchive = $this->getMatchItemByCondition($goodsBase, CommodityMapping::instance()->barcode, 'BarCode');
        $nameMatchArchive = $this->getMatchItemByCondition($goodsBase, CommodityMapping::instance()->barcode, 'Name');
        return [
            'barCodeMatchArchive' => $barCodeMatchArchive,
            'nameMatchArchive' => $nameMatchArchive
        ];
    }

    /**
     * 获取修改的主资料
     * @param $base
     * @param $baseKey
     * @param $conditionKey
     * @return array
     */
    private function getMatchItemByCondition($base, $baseKey, $conditionKey): array
    {
        $condition = array_column($base, CommodityMapping::instance()->goodstype, $baseKey);
        $where = [];
        foreach ($condition as $key => $value) {
            $where[] = [
                [$conditionKey, '=', $key],
                ['CommodityType', '=', $value],
            ];
        }
        $awaitMatchArchivesData = CommodityArchives::instance()->select(
            ['ID', 'SKUCode', 'IsIntegrity', 'BarCode', 'CommodityType', 'Name', 'IsUseAble']
        )->orWhere($where)->get()->toArray();

        $awaitMatchArchives = [];
        foreach ($awaitMatchArchivesData as $awaitMatchArchivesDatum) {
            $awaitMatchArchiveKey = $awaitMatchArchivesDatum[$conditionKey] . '_' . $awaitMatchArchivesDatum['CommodityType'];
            $awaitMatchArchives[$awaitMatchArchiveKey] = $awaitMatchArchivesDatum;
        }
        return $awaitMatchArchives;
    }

    /**
     * 匹配主资料
     * @param $goodsMapping
     * @param $matchArchives
     * @return array
     */
    public function matchArchive($goodsMapping, $matchArchives, $supplierInfo): array
    {
        $matchedArchive = $this->getMatchedArchive($goodsMapping, $matchArchives);
        //如果没有匹配到主资料,需要生成新的主资料
        if (!empty($matchedArchive) && $supplierInfo['IsOneByOneMakeArchiveDoc'] == 0) {
            if ($supplierInfo['IsTryUpdateCommodityArchives'] == 1 && $matchArchives['IsUseAble'] == 0) {
                CommodityArchives::instance()->where('ID', $matchArchives['ID'])->update(['IsUseAble' => 1]);
                $matchedArchive['IsUseAble'] = 1;
            }
        } else {
            $matchedArchive = $this->addNewArchive($goodsMapping, $supplierInfo['IsTryUpdateCommodityArchives']);
        }
        $goodsMapping['base']['CommodityArchivesID'] = $matchedArchive['goodsId'];
        $goodsMapping['base']['SKUCode'] = $matchedArchive['skuCode'];
        return [
            'base' => $goodsMapping['base'],
            'isIntegrity' => $matchedArchive['IsIntegrity'],
            'isUseAble' => $matchedArchive['IsUseAble']
        ];
    }

    /**
     * 匹配主资料
     * @param $goodsBase
     * @param $matchArchives
     * @return array
     */
    private function getMatchedArchive($goodsBase, $matchArchives): array
    {
        $matchedArchive = [];
        $goodsBaseType = $goodsBase[CommodityMapping::instance()->goodstype];
        $barCodeCondition = $goodsBase[CommodityMapping::instance()->barcode] . '_' . $goodsBaseType;
        if (isset($matchArchives['barCodeMatchArchive'][$barCodeCondition])) {
            $matchedArchive = $matchArchives['barCodeMatchArchive'][$barCodeCondition];
        } else {
            //没匹配再用名称匹配
            $nameCondition = $goodsBase[CommodityMapping::instance()->name] . '_' . $goodsBaseType;
            if (isset($matchArchives['nameMatchArchive'][$nameCondition])) {
                $matchedArchive = $matchArchives['nameMatchArchive'][$nameCondition];
            }
        }
        return $matchedArchive;
    }

    /**
     * 生成新的主资料
     * @param $goodsBase
     * @param $isTryUpdateCommodityArchives
     * @return array
     */
    private function addNewArchive($goodsMapping, $isTryUpdateCommodityArchives)
    {
        $goodsBase = $goodsMapping['base'];
        $barCode = $goodsBase[CommodityMapping::instance()->barcode] ?? '';
        //判断国际条码是否异常
        if (!preg_match('/^[0-9A-Za-z]+$/', $barCode) || !preg_match('/[^0]/', $barCode) || empty($barCode)) {
            return ['goodsId' => 0, 'skuCode' => '', 'IsIntegrity' => 0, 'IsUseAble' => 0];
        }
        //处理图片
        $images = json_decode(($goodsBase[CommodityMapping::instance()->imageUrl] ?? "[]"), true);
        if (!is_array($images)) {
            $images = [];
        }
        $description = $goodsBase[CommodityMapping::instance()->description] ?? '';
        $this->getRedisObj();
        $archiveId = IdService::instance()->getOtherID();
        //获取分类Id
        $classIds = ClassInfoService::instance()->getArchiveIds($goodsBase[CommodityMapping::instance()->classify]);
        $currentDate = date('Y-m-d H:i:s');
        $saveArchive = [
            'ID' => $archiveId,
            'Name' => $goodsBase[CommodityMapping::instance()->name],
            'MarketPrice' => $goodsMapping['other']['marketPrice'] ?? 0,
            'SKUCode' => SkuCodeBuilderService::instance()->getCode(),
            'CountryID' => CountryInfoService::instance()->getArchiveId($goodsBase[CommodityMapping::instance()->originPlace]),
            'UnitID' => UnitInfoService::instance()->getArchiveId($goodsBase[CommodityMapping::instance()->uinit]),
            'BrandID' => BrandInfoService::instance()->getArchiveId($goodsBase[CommodityMapping::instance()->brand]),
            'FirstClassificationID' => $classIds['FirstClassificationID'],
            'SecondClassificationID' => $classIds['SecondClassificationID'],
            'ThirdClassificationID' => $classIds['ThirdClassificationID'],
            'SpuID' => 0,
            'IsForbidden' => 0,
            'BarCode' => $barCode,
            'Weight' => $goodsMapping['other']['weight'] ?? 0,
            'CommodityType' => $goodsBase[CommodityMapping::instance()->goodstype],
            'FreightTemplateID' => 1,
            'IsIntegrity' => 0,
            'IsUseAble' => 0,
            'CreateTime' => $currentDate,
            'UpdateTime' => $currentDate,
            'IsDeleted' => 0
        ];
        if ($saveArchive['BrandID'] && $saveArchive['ThirdClassificationID'] && $saveArchive['CountryID'] && !empty($images) && !empty($description)) {
            $saveArchive['IsIntegrity'] = 1;
            $saveArchive['IsUseAble'] = 1;
        }

        if ($isTryUpdateCommodityArchives == 1) {
            $saveArchive['IsUseAble'] = 1;
        }

        CommodityArchives::instance()->startTrans();
        try {
            CommodityArchives::instance()->insert($saveArchive);
            $saveArchiveDetail = [
                'ID' => IdService::instance()->getOtherID(),
                'CommodityInfoID' => $archiveId,
                'CreateTime' => $currentDate,
                'UpdateTime' => $currentDate,
            ];
            if (!empty($images)) {
                $saveArchiveDetail['Images'] = json_encode($images, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                $saveArchiveDetail['HasImage'] = 1;
            }
            if (!empty($images)) {
                $saveArchiveDetail['Description'] = $description;
                $saveArchiveDetail['HasDes'] = 1;
            }
            CommodityDescription::instance()->insert($saveArchiveDetail);
            CommodityArchives::instance()->commit();
        } catch (\Exception $exception) {
            CommodityArchives::instance()->rollback();
            return ['goodsId' => 0, 'skuCode' => '', 'IsIntegrity' => 0, 'IsUseAble' => 0];
        }
        return [
            'goodsId' => $archiveId,
            'skuCode' => $saveArchive['SKUCode'],
            'IsIntegrity' => $saveArchive['IsIntegrity'],
            'IsUseAble' => $saveArchive['IsUseAble'],
        ];
    }

    /**
     * 修改重量
     * @param $weight
     * @param $commodityArchivesId
     * @return array
     */
    public function changeCommodityArchivesWeight($weight, $commodityArchivesId):array
    {
        CommodityArchives::instance()->where('ID', $commodityArchivesId)->update([
            'Weight' => $weight,
            'UpdateTime' => date('Y-m-d H:i:s')
        ]);
        return Normal::returnSuccessCode();
    }


}